package com.amkai.aes.webservice.binary.objecthandler.inventory;

import java.util.ArrayList;
import java.util.List;

public class HQLWhereNodeFactory {
	private static HQLWhereNodeFactory instance = new HQLWhereNodeFactory();

	public static HQLWhereNode createAndNode() {
		return instance.new HQLWhereAndNode();
	}

	public static HQLWhereNode createOrNode() {
		return instance.new HQLWhereOrNode();
	}

	public static HQLWhereNode createParametrizedConditionNode(String condition,
			Object value) {
		return instance.new HQLConditionNode(condition, value);
	}

	public static HQLWhereNode createSimpleConditionNode(String condition) {
		return instance.new HQLConditionNode(condition);
	}
	
	
	
	
	private class HQLConditionNode implements HQLWhereNode {
		
		private String condition;
		private Object value;
		private boolean hasValue;
		
		public HQLConditionNode(String condition) {
			this(condition, null, false);
		}

		public HQLConditionNode(String condition, Object value) {
			this(condition, value, true);
		}
		
		private HQLConditionNode(String condition, Object value, boolean hasValue) {
			this.condition = condition;
			this.value = value;
			this.hasValue = hasValue;
		}

		@Override
		public void addChild(HQLWhereNode childNode) {
		}

		@Override
		public Object getValue() {
			return value;
		}

		@Override
		public boolean hasValue() {
			return hasValue;
		}

		@Override
		public boolean isEmpty() {
			return true;
		}

		@Override
		public void walk(StringBuilder query, List<Object> params) {
			query.append(condition);
			if (hasValue) {
				params.add(value);
			}
		}
		
	}
	
	
	private abstract class HQLContainerNode implements HQLWhereNode {
		private List<HQLWhereNode> childNodes = new ArrayList<HQLWhereNode>();

		@Override
		public void addChild(HQLWhereNode childNode) {
			if (childNode == null) return;
			childNodes.add(childNode);
		}

		@Override
		public Object getValue() {
			return null;
		}

		@Override
		public boolean hasValue() {
			return false;
		}

		@Override
		public boolean isEmpty() {
			return childNodes.isEmpty();
		}

		@Override
		public void walk(StringBuilder query, List<Object> params) {
			if (childNodes.size() > 1) {
				query.append('(');
			}
			boolean first = true;
			for (HQLWhereNode node : childNodes) {
				if (!first) {
					query.append(" " + getSeparatorKeyword() + " ");
				}
				first = false;
				node.walk(query, params);
			}
			if (childNodes.size() > 1) {
				query.append(')');
			}
		}
		
		public abstract String getSeparatorKeyword();
		
	}
	private class HQLWhereAndNode extends HQLContainerNode {

		@Override
		public String getSeparatorKeyword() {
			return "and";
		}
		
	}
	
	private class HQLWhereOrNode extends HQLContainerNode {

		@Override
		public String getSeparatorKeyword() {
			return "or";
		}
		
	}

}
